﻿using System;
using System.Threading;

class Tetris
{
    static readonly int[,] Shapes = new int[7, 4]
    {
        { 0, 1, 2, 3 },{ 0, 1, 2, 5 },{ 0, 1, 5, 6 },{ 1, 2, 4, 5 },{ 0, 4, 5, 6 },{ 2, 4, 5, 6 },{ 1, 3, 4, 5 }
    };

    const int WIDTH = 10;
    const int HEIGHT = 20;

    static void Main()
    {
        Console.WriteLine("Create By 天球生物");
        System.Threading.Thread.Sleep(3000);
        Console.CursorVisible = false;
        Console.BackgroundColor = ConsoleColor.Black;
        
        StartGame();
    }

    static void StartGame()
    {
        Console.Clear();

        int[,] grid = new int[HEIGHT, WIDTH];

        while (true)
        {
            
            int[] block = CreateBlock();
            int x = WIDTH / 2 - 1;
            int y = 0;

            if (!CanMove(grid, block, x, y))
            {
                Console.SetCursorPosition(WIDTH, 0);
                Console.WriteLine("游戏结束!");
                Console.WriteLine("按任意键重新开始");
                Console.ReadKey(true);
                StartGame();
            }

            while (CanMove(grid, block, x, y + 1))
            {
                if (Console.KeyAvailable)
                {
                    var key = Console.ReadKey(true).Key;

                    switch (key)
                    {
                        case ConsoleKey.UpArrow:
                            var rotated = RotateClockwise(block);
                            if (CanMove(grid, rotated, x, y)) block = rotated;
                            break;
                        case ConsoleKey.DownArrow:
                            var rotatedCCW = RotateCounterClockwise(block);
                            if (CanMove(grid, rotatedCCW, x, y)) block = rotatedCCW;
                            break;
                        case ConsoleKey.LeftArrow:
                            if (CanMove(grid, block, x - 1, y)) x--;
                            break;
                        case ConsoleKey.RightArrow:
                            if (CanMove(grid, block, x + 1, y)) x++;
                            break;
                    }
                }
                y++;
                Draw(grid, block, x, y);
                Thread.Sleep(200);
            }

            for (int i = 0; i < 4; i++)
            {
                int row = y + block[i] / 2;
                int col = x + block[i] % 2;
                if (row >= 0) grid[row, col] = 1;
            }
            RemoveFullRows(grid);
        }
    }

    static void Draw(int[,] grid, int[] block, int x, int y)
    {
        Console.SetCursorPosition(0, 0);
        for (int ay = 0; ay < HEIGHT; ay++)
        {
            for (int ax = 0; ax < WIDTH; ax++)
            {
                bool isBlock = false;

                for (int i = 0; i < 4; i++)
                {
                    int by = block[i] / 2;
                    int bx = block[i] % 2;

                    if (ay == y + by && ax == x + bx)
                    {
                        isBlock = true;
                        break;
                    }
                }
                Console.ForegroundColor = grid[ay, ax] == 1 || isBlock ? ConsoleColor.Green : ConsoleColor.Black;
                Console.Write("██");
            }
            Console.WriteLine();
        }
    }

    static int[] CreateBlock()
    {
        int type = new Random().Next(0, 7);
        int[] block = new int[4];

        for (int i = 0; i < 4; i++)
            block[i] = Shapes[type, i];

        return block;
    }

    static int[] RotateClockwise(int[] block)
    {
        int[] rotated = new int[4];

        for (int i = 0; i < 4; i++)
        {
            int x = 3 - block[i] / 2;
            int y = block[i] % 2;
            rotated[i] = y * 2 + x;
        }
        return rotated;
    }

    static int[] RotateCounterClockwise(int[] block)
    {
        int[] rotated = new int[4];

        for (int i = 0; i < 4; i++)
        {
            int x = block[i] % 2;
            int y = 3 - block[i] / 2;
            rotated[i] = y * 2 + x;
        }
        return rotated;
    }

    static bool CanMove(int[,] grid, int[] block, int x, int y)
    {
        for (int i = 0; i < 4; i++)
        {
            int blockX = x + block[i] % 2;
            int blockY = y + block[i] / 2;

            if (blockX < 0 || blockX >= WIDTH || blockY >= HEIGHT)
                return false;

            if (blockY >= 0 && grid[blockY, blockX] == 1)
                return false;
        }
        return true;
    }

    static void RemoveFullRows(int[,] grid)
    {
        for (int ay = HEIGHT - 1; ay >= 0; ay--)
        {
            bool isRowFull = true;

            for (int ax = 0; ax < WIDTH; ax++)
            {
                if (grid[ay, ax] == 0)
                {
                    isRowFull = false;
                    break;
                }
            }
            if (isRowFull)
            {
                for (int row = ay; row > 0; row--)
                    for (int ax = 0; ax < WIDTH; ax++)
                        grid[row, ax] = grid[row - 1, ax];

                ay++;
            }
        }
    }
}